SecurityUtils 使用示例
场景一:获取用户信息
1.1 获取用户(可能为 null)
@GetMapping("/user/info")
public ResponseEntity<?> getUserInfo() {
LoginUserVO user = SecurityUtils.getLoginUser();
if (user == null) {
return ResponseEntity.ok(Map.of("message", "请先登录"));
}
return ResponseEntity.ok(user);
}
1.2 获取用户(必须登录)
@PostMapping("/like")
public ResponseEntity<?> likeArticle(@RequestParam Long articleId) {
// 此方法需要用户已登录
LoginUserVO user = SecurityUtils.requireLoginUser(); // 未登录时抛异常
Long userId = user.getId();
articleService.like(articleId, userId);
return ResponseEntity.ok("点赞成功");
}
1.3 简化获取用户 ID
@PostMapping("/comment")
public ResponseEntity<?> createComment(@RequestBody CommentRequest request) {
// 直接获取用户 ID(简化写法)
Long userId = SecurityUtils.requireUserId();
Comment comment = new Comment();
comment.setUserId(userId);
comment.setContent(request.getContent());
commentService.save(comment);
return ResponseEntity.ok("评论成功");
}
场景二:权限校验(失败抛异常)
2.1 单个权限检查
@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody CreateUserRequest request) {
// 需要 system:user:add 权限,没有则抛异常
SecurityUtils.checkPermission("system:user:add");
User user = userService.createUser(request);
return ResponseEntity.ok(user);
}
2.2 多权限检查(AND 逻辑)
@PostMapping("/publish-article")
public ResponseEntity<?> publishArticle(@RequestBody ArticleRequest request) {
// 需要同时拥有 content:create 和 content:publish 权限
SecurityUtils.checkPermission("content:create", "content:publish");
Article article = articleService.createAndPublish(request);
return ResponseEntity.ok(article);
}
2.3 多权限检查(OR 逻辑)
@PostMapping("/review-content")
public ResponseEntity<?> reviewContent(@RequestBody ReviewRequest request) {
// 拥有任一权限即可:审核或发布权限
SecurityUtils.checkAnyPermission("content:review", "content:publish");
contentService.review(request);
return ResponseEntity.ok("审核成功");
}
2.4 角色检查
@GetMapping("/admin/dashboard")
public ResponseEntity<?> getAdminDashboard() {
// 需要 admin 角色
SecurityUtils.checkRole("admin");
return ResponseEntity.ok(adminService.getDashboard());
}
2.5 多角色检查(OR 逻辑)
@GetMapping("/system/logs")
public ResponseEntity<?> getSystemLogs() {
// 拥有任一角色即可:管理员或超级管理员
SecurityUtils.checkAnyRole("admin", "super_admin");
return ResponseEntity.ok(logService.getLogs());
}
场景三:权限判断(返回 boolean)
3.1 条件显示功能
@GetMapping("/article/{id}")
public ResponseEntity<?> getArticle(@PathVariable Long id) {
Article article = articleService.getById(id);
// 判断当前用户是否可以编辑此文章
boolean canEdit = SecurityUtils.hasPermission("content:edit")
&& article.getUserId().equals(SecurityUtils.getUserId());
// 判断当前用户是否是管理员
boolean isAdmin = SecurityUtils.isAdmin();
return ResponseEntity.ok(Map.of(
"article", article,
"canEdit", canEdit,
"isAdmin", isAdmin
));
}
3.2 动态菜单根据权限显示
@GetMapping("/menu")
public ResponseEntity<?> getMenu() {
List<MenuItem> menus = new ArrayList<>();
// 基础菜单(所有人都有)
menus.add(new MenuItem("首页", "/home"));
menus.add(new MenuItem("个人资料", "/profile"));
// 根据权限添加菜单
if (SecurityUtils.hasPermission("content:create")) {
menus.add(new MenuItem("创建内容", "/create"));
}
if (SecurityUtils.hasPermission("content:review")) {
menus.add(new MenuItem("内容审核", "/review"));
}
if (SecurityUtils.isAdmin()) {
menus.add(new MenuItem("用户管理", "/admin/users"));
menus.add(new MenuItem("系统配置", "/admin/config"));
}
return ResponseEntity.ok(menus);
}
场景四:数据级权限(个人隐私数据)
4.1 只能查看自己的信息
@GetMapping("/user/{userId}/profile")
public ResponseEntity<?> getProfile(@PathVariable Long userId) {
// 检查:只有本人或管理员才能查看个人资料
SecurityUtils.checkSelfOrAdmin(userId);
UserVO profile = userService.getProfile(userId);
return ResponseEntity.ok(profile);
}
4.2 修改个人信息
@PutMapping("/user/{userId}/profile")
public ResponseEntity<?> updateProfile(
@PathVariable Long userId,
@RequestBody UpdateProfileRequest request) {
// 权限检查:只能修改自己的信息
SecurityUtils.checkSelfOrAdmin(userId);
userService.updateProfile(userId, request);
return ResponseEntity.ok("修改成功");
}
4.3 删除账户
@DeleteMapping("/user/{userId}")
public ResponseEntity<?> deleteAccount(@PathVariable Long userId) {
// 权限检查:只有本人或超级管理员可以删除账户
SecurityUtils.checkSelfOrAnyAdmin(userId);
userService.deleteAccount(userId);
return ResponseEntity.ok("账户已删除");
}
场景五:资源所有权检查
5.1 删除自己的文章
@Service
public class ArticleService {
public void deleteArticle(Long articleId) {
Article article = articleRepository.findById(articleId);
if (article == null) {
throw new BusinessException(ErrorCode.NOT_FOUND, "文章不存在");
}
// 检查所有权:只有创建者能删除
SecurityUtils.checkOwner(article.getUserId());
articleRepository.delete(article);
log.info("文章删除成功,articleId: {}", articleId);
}
}
5.2 删除评论
@Service
public class CommentService {
public void deleteComment(Long commentId) {
Comment comment = commentRepository.findById(commentId);
if (comment == null) {
throw new BusinessException(ErrorCode.NOT_FOUND, "评论不存在");
}
// 权限检查:评论作者或文章作者或管理员可以删除
Long currentUserId = SecurityUtils.requireUserId();
Long commentAuthorId = comment.getUserId();
Article article = articleRepository.findById(comment.getArticleId());
Long articleAuthorId = article.getUserId();
boolean isCommentAuthor = currentUserId.equals(commentAuthorId);
boolean isArticleAuthor = currentUserId.equals(articleAuthorId);
boolean isAdmin = SecurityUtils.isAdmin();
if (!isCommentAuthor && !isArticleAuthor && !isAdmin) {
throw new BusinessException(ErrorCode.FORBIDDEN, "无权删除此评论");
}
commentRepository.delete(comment);
}
}
场景六:Service 层权限检查
6.1 在 Service 中检查权限
@Service
@Slf4j
public class OrderService {
/**
* 创建订单 - 在 Service 中检查权限
*/
public OrderVO createOrder(CreateOrderRequest request) {
// 检查权限(也可以在 Controller 中检查)
SecurityUtils.checkPermission("order:create");
Long userId = SecurityUtils.requireUserId();
Order order = new Order();
order.setUserId(userId);
order.setItems(request.getItems());
orderRepository.save(order);
log.info("订单创建成功,userId: {}, orderId: {}", userId, order.getId());
return OrderVO.fromEntity(order);
}
/**
* 修改订单 - 数据级权限检查
*/
public void updateOrder(Long orderId, UpdateOrderRequest request) {
Order order = orderRepository.findById(orderId);
if (order == null) {
throw new BusinessException(ErrorCode.NOT_FOUND, "订单不存在");
}
// 检查权限:只有订单所有者或管理员可以修改
SecurityUtils.checkSelfOrAdmin(order.getUserId());
order.setStatus(request.getStatus());
orderRepository.save(order);
log.info("订单修改成功,orderId: {}", orderId);
}
/**
* 查看订单 - 数据级权限检查
*/
public OrderVO getOrder(Long orderId) {
Order order = orderRepository.findById(orderId);
if (order == null) {
throw new BusinessException(ErrorCode.NOT_FOUND, "订单不存在");
}
// 检查权限:只有订单所有者或管理员可以查看
SecurityUtils.checkSelfOrAdmin(order.getUserId());
return OrderVO.fromEntity(order);
}
/**
* 导出订单 - 权限检查
*/
public void exportOrders(List<Long> orderIds) {
// 检查是否有导出权限
if (!SecurityUtils.hasPermission("order:export")) {
throw new BusinessException(ErrorCode.FORBIDDEN, "没有导出权限");
}
// 执行导出逻辑
performExport(orderIds);
}
}
场景七:认证状态检查
7.1 需要登录的操作
@PostMapping("/favorite")
public ResponseEntity<?> addFavorite(@RequestParam Long articleId) {
// 强制要求用户已登录
SecurityUtils.requireAuthenticated();
Long userId = SecurityUtils.getUserId();
favoriteService.addFavorite(userId, articleId);
return ResponseEntity.ok("已收藏");
}
7.2 不能登录的操作
@PostMapping("/auth/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
// 防止重复登录
SecurityUtils.requireNotAuthenticated();
UserVO user = userService.login(request);
return ResponseEntity.ok(user);
}
7.3 条件性功能
@GetMapping("/article/{id}")
public ResponseEntity<?> getArticle(@PathVariable Long id) {
Article article = articleService.getById(id);
Map<String, Object> response = new HashMap<>();
response.put("article", article);
// 只有已登录用户才能看到点赞按钮
if (SecurityUtils.isAuthenticated()) {
Long userId = SecurityUtils.getUserId();
boolean liked = favoriteService.isLiked(userId, id);
response.put("liked", liked);
response.put("canComment", true);
} else {
response.put("message", "请登录后进行点赞和评论");
}
return ResponseEntity.ok(response);
}
最佳实践
✅ DO(该做的)
-
使用
requireLoginUser()而不是getLoginUser()// ✅ 好:明确要求用户已登录 LoginUserVO user = SecurityUtils.requireLoginUser(); // ❌ 不好:需要额外的 null 检查 LoginUserVO user = SecurityUtils.getLoginUser(); if (user == null) { ... } -
在 Controller 中进行权限校验
// ✅ 好:权限校验在 Controller 层 @PostMapping("/users") public ResponseEntity<?> createUser() { SecurityUtils.checkPermission("system:user:add"); return ResponseEntity.ok(userService.createUser(...)); } -
在 Service 中进行数据级权限检查
// ✅ 好:数据权限检查在 Service 层 public void updateOrder(Long orderId) { Order order = orderRepository.findById(orderId); SecurityUtils.checkSelfOrAdmin(order.getUserId()); // 执行更新 } -
使用具体的权限码
// ✅ 好:使用常量避免拼写错误 public static final String PERMISSION_USER_ADD = "system:user:add"; SecurityUtils.checkPermission(PERMISSION_USER_ADD);
❌ DON'T(不该做的)
- 直接使用 getLoginUser() 而忘记 null 检查
- 权限校验在多个地方重复
- 使用硬编码的权限字符串
- 忘记进行数据级权限检查
权限常量定义
public class PermissionConstants {
// 用户管理
public static final String USER_ADD = "system:user:add";
public static final String USER_EDIT = "system:user:edit";
public static final String USER_DELETE = "system:user:delete";
public static final String USER_VIEW = "system:user:view";
// 内容管理
public static final String CONTENT_CREATE = "content:create";
public static final String CONTENT_EDIT = "content:edit";
public static final String CONTENT_DELETE = "content:delete";
public static final String CONTENT_PUBLISH = "content:publish";
public static final String CONTENT_REVIEW = "content:review";
// 订单管理
public static final String ORDER_CREATE = "order:create";
public static final String ORDER_EXPORT = "order:export";
public static final String ORDER_CANCEL = "order:cancel";
}
// 在 Controller 中使用
@PostMapping("/users")
public ResponseEntity<?> createUser() {
SecurityUtils.checkPermission(PermissionConstants.USER_ADD);
return ResponseEntity.ok(userService.createUser(...));
}
项目分区导航:⬅️ 03-权限校验最佳实践模型代码 | 04-SecurityUtils 使用示例 | ➡️ 05-权限控制模型
💬 评论